package com.suning.sawp.service.impl.bi;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import com.suning.framework.dal.client.DalClient;
import com.suning.sawp.intf.bi.BiDataTableRouteService;
import com.suning.sawp.service.util.DateUtils;

/**
 * 
 * BI数据处理工具类<br> 
 * 〈功能详细描述〉
 *
 * @author 12061818
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
@Service("biDataTableRouteService")
public class BiDataTableRouteServiceImpl implements BiDataTableRouteService {
    
    /**
     * yyyyMMdd
     */
    private static final Pattern YYYYMMDD_PATTERN = Pattern.compile("\\d{4}\\d{2}\\d{2}");
    
    /**
     * yyyyMM
     */
    private static final Pattern YYYYMM_PATTERN = Pattern.compile("\\d{4}\\d{2}");
    
    /**
     * 重跑数据表后缀名
     */
    private static final String REWIRITE_TABLE_SUFFIX = "_REW";
    
    /**
     * BI重抛数据已经入到重跑数据表
     */
    private static final String FINISH_RECOVER = "1";
    
    /**
     * BI重抛数据尚未处理入库
     */
    private static final String NO_FINISH_RECOVER = "0";
    
    @Resource
    DalClient dalClient;
    
    @Override
    public String optWriteGetTableIndex(String statisDate, boolean goRewiter) {
        return getTableIndex(statisDate, goRewiter, true);
    }
    
    @Override
    public String optReadGetTableIndex(String statisDate, boolean goRewiter) {
        return getTableIndex(statisDate, goRewiter, false);
    }
    
    /**
     * 
     * 功能描述: 取BI数据表下标<br>
     * 〈功能详细描述〉
     *
     * @param statisDate 统计日期
     * @param goRewiter 是否走重跑数据逻辑 true-走重跑数据逻辑；false-不走
     * @param optFlag 操作类型  写操作-true，读操作-false
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    private String getTableIndex(String statisDate, boolean goRewiter, boolean optFlag) {
        String indexStr = "";
        // BI 抛过来的日期目前分两种，yyyyMM和yyyyMMdd，且以201508为原点开始计算
        // 校验日期格式是否符合规范, 如果某条数据statisDate不符合规范，则不选择表，丢给DB执行报错，计入报错行记录
        Matcher yyyyMMddMatcher = YYYYMMDD_PATTERN.matcher(statisDate);
        Matcher yyyyMMMatcher = YYYYMM_PATTERN.matcher(statisDate);
        if (StringUtils.isNotBlank(statisDate) && 
                (yyyyMMddMatcher.matches() || yyyyMMMatcher.matches())) {
            // 截取年份和月份
            int year = Integer.parseInt(statisDate.substring(0, 4));
            String monthStr = statisDate.substring(4, 6);
            int month = Integer.parseInt(monthStr);
            int index = (12 * (year - 2015) + month - 8) % 3;
            indexStr = String.valueOf(index);
            if (goRewiter) {
                // 需要走重跑数据的备份表数据
                // 判断statisDate是否为当前日期的上个月
                Calendar calendar = Calendar.getInstance();
                calendar.add(Calendar.MONTH, -1);
                int lastMonth = calendar.get(Calendar.MONTH) + 1;
                if (month == lastMonth) {
                    // 当前时间的上个月且为需要走重跑数据的备份表数据
                    // 取重抛数据记录表中取上月重跑数据表是否已经重新备份完新数据标志
                    String recoverFinish =getBiRecoverFinishFlag(DateUtils.getLastMonth());
                    if (optFlag) {
                        // 写操作
                        if (StringUtils.isBlank(recoverFinish)) {
                            // 假如从重抛数据记录表中取不到重跑数据标志，则默认认为数据已经重跑过了，防止将BI重抛数据重复入库
                            recoverFinish = FINISH_RECOVER;
                            // 返回下标为null，不做新的写库操作
                            indexStr = null;
                        }
                        if (NO_FINISH_RECOVER.equals(recoverFinish)) {
                            indexStr += REWIRITE_TABLE_SUFFIX;
                        }
                    } else {
                        // 读操作
                        if (StringUtils.isBlank(recoverFinish)) {
                            // 假如从重抛数据记录表中取不到重跑数据标志，则默认认为数据尚未处理，依旧取老表数据
                            recoverFinish = NO_FINISH_RECOVER;
                        }
                        if (FINISH_RECOVER.equals(recoverFinish)) {
                            indexStr += REWIRITE_TABLE_SUFFIX;
                        }
                    }
                }
            }
        }
        return indexStr;
    }
    
    /**
     * 
     * 功能描述: 取月份重抛BI数据处理完成与否标志<br>
     * 〈功能详细描述〉
     *
     * @param dateStr
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    private String getBiRecoverFinishFlag(String month) {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("month", month);
        String dealStatus = 
                dalClient.queryForObject("BI_RECOVER_RECORD.QUERY_DEAL_STATUS_BY_MONTH", paramMap, String.class);
        return dealStatus;
    }

    @Override
    public void finishBiDataRecover() {
        // 取上个月份yyyyMM
        String lastMonth = DateUtils.getLastMonth();
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("month", lastMonth);
        paramMap.put("status", FINISH_RECOVER);
        paramMap.put("updateTime", new Date());
        dalClient.execute("BI_RECOVER_RECORD.UPDATE_DEAL_STATUS_BY_MONTH", paramMap);
        
        String tihsMonth = DateUtils.getThisMonth();
        paramMap.clear();
        paramMap.put("month", tihsMonth);
        paramMap.put("status", NO_FINISH_RECOVER);
        paramMap.put("createTime", new Date());
        paramMap.put("updateTime", new Date());
        dalClient.execute("BI_RECOVER_RECORD.ADD_NEW_RECOVER_RECORD", paramMap);
    }
    
}
